package umg.os.kernel.scheduler;

import java.util.Comparator;
import java.util.InputMismatchException;

import umg.os.kernel.Dispatcher;
import umg.os.kernel.Kernel;
import umg.os.process.ProcessControlBlock;
import umg.os.process.ProcessControlBlock.ProcessStatus;

public class RoundRobin extends Scheduler {

	private final short sliceTimeUnits;
	private short nextSliceIn;
	
	public RoundRobin(short sliceTimeUnits) {
		if (sliceTimeUnits <= 0) {
			throw new InputMismatchException("The slice time should be at lest 1");
		}
		nextSliceIn = this.sliceTimeUnits = sliceTimeUnits;
	}

	@Override
	public void nextTimeUnit() {
		if(!Kernel.getInstance().isExecuting()){
			Dispatcher.getInstance().switchExecutingProcess();
		}
		if (nextSliceIn-- == 0) {
			Dispatcher.getInstance().switchExecutingProcess();
		}
	}

	@Override
	public ProcessControlBlock requestNextProcessToExecute() {
		nextSliceIn = sliceTimeUnits;
		return ReadyList.getInstance().getNextWaitingProcess();
	}

	@Override
	public Comparator<ProcessControlBlock> getSorter() {
		return new Comparator<ProcessControlBlock>() {

			@Override
			public int compare(ProcessControlBlock pcb1, ProcessControlBlock pcb2) {
				return ((Long)pcb1.arrivalTime).compareTo((Long)pcb2.arrivalTime);
			}
			
		};
	}

	@Override
	public void dispatcherJustSwitch(ProcessControlBlock processDeallocated) {
		if(processDeallocated== null){
			System.err.println("Si este no es el inicio esta mal");
			return;
		}
		if (!processDeallocated.getStatus().equals(ProcessStatus.TERMINATED)) {
			ReadyList.getInstance().scheduleAtLast(processDeallocated);
		}
	}

}
